Pass in initialized Source types into compile op
authorCarl Lerche <me@carllerche.com>
Fri, 25 Jul 2014 18:35:11 +0000 (11:35 -0700)
committerCarl Lerche <me@carllerche.com>
Fri, 25 Jul 2014 18:35:11 +0000 (11:35 -0700)
src/cargo/core/mod.rs
src/cargo/core/registry.rs
src/cargo/core/resolver.rs
src/cargo/core/source.rs
src/cargo/ops/cargo_compile.rs
src/cargo/ops/cargo_rustc/context.rs
src/cargo/ops/cargo_rustc/fingerprint.rs
src/cargo/ops/cargo_rustc/mod.rs
src/cargo/sources/path.rs
src/cargo/util/graph.rs

index 80fb64eed73ffa954d7e925e5058f050e6d8faa3..6f63055070bc5992b034278601947c3cd920772b 100644 (file)
@@ -21,6 +21,7 @@ pub use self::package_id::{
 pub use self::source::{
     Source,
     SourceId,
+    SourceMap,
     SourceSet,
     GitKind,
     PathKind,
index 83cb1c75950c452edd65daeba95ecdaf01cf6298..e5752e33668a35f1f51c6a91c2994f85540c8eed 100644 (file)
@@ -1,5 +1,6 @@
+use std::collections::HashMap;
 use std::vec::Vec;
-use core::{Source, SourceId, Summary, Dependency, PackageId, Package};
+use core::{Source, SourceId, SourceMap, Summary, Dependency, PackageId, Package};
 use util::{CargoResult, ChainError, Config, human};
 
 pub trait Registry {
@@ -16,10 +17,9 @@ impl Registry for Vec<Summary> {
 }
 
 pub struct PackageRegistry<'a> {
-    sources: Vec<Box<Source>>,
+    sources: SourceMap,
     overrides: Vec<Summary>,
     summaries: Vec<Summary>,
-    searched: Vec<SourceId>,
     config: &'a mut Config<'a>
 }
 
@@ -44,10 +44,9 @@ impl<'a> PackageRegistry<'a> {
 
     fn empty<'a>(config: &'a mut Config<'a>) -> PackageRegistry<'a> {
         PackageRegistry {
-            sources: vec!(),
+            sources: SourceMap::new(),
             overrides: vec!(),
             summaries: vec!(),
-            searched: vec!(),
             config: config
         }
     }
@@ -60,7 +59,7 @@ impl<'a> PackageRegistry<'a> {
         // source
         let mut ret = Vec::new();
 
-        for source in self.sources.iter() {
+        for source in self.sources.sources() {
             try!(source.download(package_ids));
             let packages = try!(source.get(package_ids));
 
@@ -74,14 +73,20 @@ impl<'a> PackageRegistry<'a> {
         Ok(ret)
     }
 
+    pub fn move_sources(self) -> SourceMap {
+        self.sources
+    }
+
     fn ensure_loaded(&mut self, namespace: &SourceId) -> CargoResult<()> {
-        if self.searched.contains(namespace) { return Ok(()); }
+        if self.sources.contains(namespace) {
+            return Ok(());
+        }
+
         try!(self.load(namespace, false));
         Ok(())
     }
 
     fn load(&mut self, namespace: &SourceId, override: bool) -> CargoResult<()> {
-
         (|| {
             let mut source = namespace.load(self.config);
             let dst = if override {&mut self.overrides} else {&mut self.summaries};
@@ -97,10 +102,7 @@ impl<'a> PackageRegistry<'a> {
             }
 
             // Save off the source
-            self.sources.push(source);
-
-            // Track that the source has been searched
-            self.searched.push(namespace.clone());
+            self.sources.insert(namespace, source);
 
             Ok(())
         }).chain_error(|| human(format!("Unable to update {}", namespace)))
index f830e81b593b881b263bc37069e23d72e9c61293..4d7411bf6e49abe72b9b112f77f480c1c575f859 100644 (file)
@@ -1,4 +1,6 @@
 use std::collections::HashMap;
+use std::fmt;
+use serialize::{Encodable, Encoder};
 use util::graph::{Nodes,Edges};
 
 use core::{
@@ -30,6 +32,12 @@ impl Resolve {
     }
 }
 
+impl fmt::Show for Resolve {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        self.graph.fmt(fmt)
+    }
+}
+
 struct Context<'a, R> {
     registry: &'a mut R,
     resolve: Resolve,
@@ -56,6 +64,7 @@ pub fn resolve<R: Registry>(root: &PackageId, deps: &[Dependency], registry: &mu
 
     let mut context = Context::new(registry);
     try!(resolve_deps(root, deps, &mut context));
+    log!(5, "  result={}", context.resolve);
     Ok(context.resolve)
 }
 
index 84c7faca283898633e33a54753e1e5a3d7515ee5..844f4bfcc22c1ebade260fd8859ce3a7842957ed 100644 (file)
@@ -1,3 +1,5 @@
+use std::collections::HashMap;
+use std::collections::hashmap::Values;
 use std::fmt;
 use std::fmt::{Show, Formatter};
 use std::hash;
@@ -211,6 +213,7 @@ impl SourceId {
     }
 
     pub fn load(&self, config: &mut Config) -> Box<Source> {
+        log!(5, "loading SourceId; {}", self);
         match self.kind {
             GitKind(..) => box GitSource::new(self, config) as Box<Source>,
             PathKind => {
@@ -225,6 +228,49 @@ impl SourceId {
     }
 }
 
+pub struct SourceMap {
+    map: HashMap<SourceId, Box<Source>>
+}
+
+pub type Sources<'a> = Values<'a, SourceId, Box<Source>>;
+
+impl SourceMap {
+    pub fn new() -> SourceMap {
+        SourceMap {
+            map: HashMap::new()
+        }
+    }
+
+    pub fn contains(&self, id: &SourceId) -> bool {
+        self.map.contains_key(id)
+    }
+
+    pub fn get(&self, id: &SourceId) -> Option<&Source> {
+        let source = self.map.find(id);
+
+        source.map(|s| {
+            let s: &Source = *s;
+            s
+        })
+    }
+
+    pub fn get_by_package_id(&self, pkg_id: &PackageId) -> Option<&Source> {
+        self.get(pkg_id.get_source_id())
+    }
+
+    pub fn insert(&mut self, id: &SourceId, source: Box<Source>) {
+        self.map.insert(id.clone(), source);
+    }
+
+    pub fn len(&self) -> uint {
+        self.map.len()
+    }
+
+    pub fn sources(&self) -> Sources {
+        self.map.values()
+    }
+}
+
 pub struct SourceSet {
     sources: Vec<Box<Source>>
 }
index a6f894d0cebaff60aafa8f5f27b96c473997f456..966848d444f5ba6f3075f9e8f72643acf270f724 100644 (file)
@@ -64,7 +64,7 @@ pub fn compile(manifest_path: &Path,
                                                    manifest_path.dir_path()));
     let source_ids = package.get_source_ids();
 
-    let (packages, resolve) = {
+    let (packages, resolve, sources) = {
         let mut config = try!(Config::new(*shell, update, jobs, target.clone()));
 
         let mut registry =
@@ -79,7 +79,7 @@ pub fn compile(manifest_path: &Path,
             human("Unable to get packages from source")
         }));
 
-        (packages, resolved)
+        (packages, resolved, registry.move_sources())
     };
 
     debug!("packages={}", packages);
@@ -92,7 +92,7 @@ pub fn compile(manifest_path: &Path,
     try!(scrape_target_config(&mut config, &user_configs));
 
     try!(ops::compile_targets(env.as_slice(), targets.as_slice(), &package,
-         &PackageSet::new(packages.as_slice()), &resolve, &mut config));
+         &PackageSet::new(packages.as_slice()), &resolve, &sources, &mut config));
 
     let test_executables: Vec<String> = targets.iter()
         .filter_map(|target| {
index 9a113e41b5302a7003e7db117bc73e6f882cb81b..8ccd14bc7f24936bab4e69f16d27008c84fc0869 100644 (file)
@@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet};
 use std::os;
 use std::str;
 
-use core::{Package, PackageId, PackageSet, Resolve, Target};
+use core::{SourceMap, Package, PackageId, PackageSet, Resolve, Target};
 use util;
 use util::{CargoResult, ChainError, internal, Config};
 
@@ -20,6 +20,7 @@ pub struct Context<'a, 'b> {
     pub rustc_version: String,
     pub config: &'b mut Config<'b>,
     pub resolve: &'a Resolve,
+    pub sources: &'a SourceMap,
 
     env: &'a str,
     host: Layout,
@@ -32,8 +33,8 @@ pub struct Context<'a, 'b> {
 }
 
 impl<'a, 'b> Context<'a, 'b> {
-    pub fn new(env: &'a str, resolve: &'a Resolve, deps: &'a PackageSet,
-               config: &'b mut Config<'b>,
+    pub fn new(env: &'a str, resolve: &'a Resolve, sources: &'a SourceMap,
+               deps: &'a PackageSet, config: &'b mut Config<'b>,
                host: Layout, target: Option<Layout>)
                -> CargoResult<Context<'a, 'b>> {
         let (target_dylib, target_exe) =
@@ -51,6 +52,7 @@ impl<'a, 'b> Context<'a, 'b> {
             target: target,
             primary: false,
             resolve: resolve,
+            sources: sources,
             package_set: deps,
             config: config,
             target_dylib: target_dylib,
index 1f6325eae7ebac22e5e14faacc5e8b0125ff6811..6d2c0f3d94f5e769a169ebaabda0372f1899970e 100644 (file)
@@ -75,7 +75,7 @@ pub fn prepare(cx: &mut Context, pkg: &Package,
 
 fn is_fresh(dep: &Package, loc: &Path, cx: &mut Context, targets: &[&Target])
             -> CargoResult<(bool, String)> {
-    let dep_fingerprint = try!(get_fingerprint(dep, cx.config));
+    let dep_fingerprint = try!(get_fingerprint(dep, cx));
     let new_pkg_fingerprint = format!("{}{}", cx.rustc_version, dep_fingerprint);
 
     let new_fingerprint = fingerprint(new_pkg_fingerprint, hash_targets(targets));
@@ -93,6 +93,14 @@ fn is_fresh(dep: &Package, loc: &Path, cx: &mut Context, targets: &[&Target])
     Ok((old_fingerprint == new_fingerprint, new_fingerprint))
 }
 
+fn get_fingerprint(pkg: &Package, cx: &Context) -> CargoResult<String> {
+    let source = cx.sources
+        .get(pkg.get_package_id().get_source_id())
+        .expect("BUG: Missing package source");
+
+    source.fingerprint(pkg)
+}
+
 fn hash_targets(targets: &[&Target]) -> u64 {
     let hasher = SipHasher::new_with_keys(0,0);
     let targets = targets.iter().map(|t| (*t).clone()).collect::<Vec<Target>>();
@@ -103,9 +111,3 @@ fn fingerprint(package: String, profiles: u64) -> String {
     let hasher = SipHasher::new_with_keys(0,0);
     util::to_hex(hasher.hash(&(package, profiles)))
 }
-
-fn get_fingerprint(pkg: &Package, config: &mut Config) -> CargoResult<String> {
-    let source_id = pkg.get_package_id().get_source_id();
-    let source = source_id.load(config);
-    source.fingerprint(pkg)
-}
index 605b7c8849eb7fa5cbbe3ee9b64c752d653e6639..c215c181a5fba6cbe8ca6c2872da28203a87e28a 100644 (file)
@@ -4,7 +4,7 @@ use std::io::{fs, UserRWX};
 use std::os;
 use semver::Version;
 
-use core::{Package, PackageId, PackageSet, Target, Resolve};
+use core::{SourceMap, Package, PackageId, PackageSet, Target, Resolve};
 use util;
 use util::{CargoResult, ProcessBuilder, CargoError, human, caused_human};
 use util::{Config, Freshness, internal, ChainError};
@@ -38,7 +38,7 @@ fn uniq_target_dest<'a>(targets: &[&'a Target]) -> Option<&'a str> {
 }
 
 pub fn compile_targets<'a>(env: &str, targets: &[&'a Target], pkg: &'a Package,
-                           deps: &PackageSet, resolve: &'a Resolve,
+                           deps: &PackageSet, resolve: &'a Resolve, sources: &'a SourceMap,
                            config: &'a mut Config<'a>) -> CargoResult<()> {
     if targets.is_empty() {
         return Ok(());
@@ -53,7 +53,7 @@ pub fn compile_targets<'a>(env: &str, targets: &[&'a Target], pkg: &'a Package,
         layout::Layout::new(root.join(target).join(dest))
     });
 
-    let mut cx = try!(Context::new(env, resolve, deps, config,
+    let mut cx = try!(Context::new(env, resolve, sources, deps, config,
                                    host_layout, target_layout));
 
     // First ensure that the destination directory exists
index dc19769563b59dcc65a4f07c3c1c8f652831d4d6..b6a3c8083bf438624bdec2f6f41486d349117379 100644 (file)
@@ -5,7 +5,7 @@ use std::io::fs;
 
 use core::{Package, PackageId, Summary, SourceId, Source};
 use ops;
-use util::{CargoResult, internal};
+use util::{CargoResult, internal, internal_error};
 
 pub struct PathSource {
     id: SourceId,
@@ -19,6 +19,7 @@ pub struct PathSource {
 impl PathSource {
 
     pub fn for_path(path: &Path) -> PathSource {
+        log!(5, "PathSource::for_path; path={}", path.display());
         PathSource::new(path, &SourceId::for_path(path))
     }
 
@@ -96,12 +97,17 @@ impl Source for PathSource {
     }
 
     fn fingerprint(&self, pkg: &Package) -> CargoResult<String> {
-        let packages = try!(self.read_packages());
+        if !self.updated {
+            return Err(internal_error("BUG: source was not updated", ""));
+        }
+
         let mut max = 0;
-        for pkg in packages.iter().filter(|p| *p == pkg) {
+
+        for pkg in self.packages.iter().filter(|p| *p == pkg) {
             let loc = pkg.get_manifest_path().dir_path();
             max = cmp::max(max, try!(walk(&loc, true)));
         }
+
         return Ok(max.to_string());
 
         fn walk(path: &Path, is_root: bool) -> CargoResult<u64> {
index 3e498b405aa151748e8520e16eb342d38d298e8d..e4aa127385f075207ec5ce90926f9859caf98b5e 100644 (file)
@@ -1,3 +1,4 @@
+use std::fmt;
 use std::hash::Hash;
 use std::collections::{HashMap, HashSet};
 use std::collections::hashmap::{Keys, SetItems};
@@ -67,3 +68,21 @@ impl<N: Eq + Hash + Clone> Graph<N> {
         self.nodes.keys()
     }
 }
+
+impl<N: fmt::Show + Eq + Hash> fmt::Show for Graph<N> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        try!(writeln!(fmt, "Graph {{"));
+
+        for (n, e) in self.nodes.iter() {
+            try!(writeln!(fmt, "  - {}", n));
+
+            for n in e.iter() {
+                try!(writeln!(fmt, "    - {}", n));
+            }
+        }
+
+        try!(write!(fmt, "}}"));
+
+        Ok(())
+    }
+}